package service

import (
	"crypto/tls"
	"fmt"
	"os"
	"qld2devservice/cons"
	"qld2devservice/utils"
	"strconv"
	"time"

	MQTT "github.com/eclipse/paho.mqtt.golang"
)

var (
	connOpts        = MQTT.NewClientOptions()
	clientConnected *MQTT.Client
	appName         string
	addBroker       string
	username        string
	password        string
)

func MqttInit() {
	var err1, err2, err5, err6 error
	appName, err1 = utils.Config.Get("appname")
	addBroker, err2 = utils.Config.Get("mqttAddBrokerNotice")
	if cons.GRPC_TEST_MODE == cons.ENUM_SERVER {
	} else if cons.GRPC_TEST_MODE == cons.ENUM_SERVER_TEST {
	} else if cons.GRPC_TEST_MODE == cons.ENUM_LOCALHOST {
		addBroker = "tcp://192.168.99.100:1883"
	}
	username, err5 = utils.Config.Get("mqttUserNameNotice")
	password, err6 = utils.Config.Get("mqttPasswordNotice")
	if err1 != nil || err2 != nil || err5 != nil || err6 != nil {
		utils.MyPrint(utils.PRINT_ERROR, err1, err2, err5, err6)
		os.Exit(1)
	}
	makeNewClient(func(client *MQTT.Client) {
		clientConnected = client
	})
	fmt.Println("打印的mqtt地址:", addBroker)
}

type NewClientHandler func(client *MQTT.Client)

func makeNewClient(makeNewClientHandler NewClientHandler) {
	connNewOpts := MQTT.NewClientOptions()
	connNewOpts.AddBroker(addBroker)
	connNewOpts.SetClientID(appName + strconv.FormatInt(time.Now().UnixNano(), 10))
	connNewOpts.SetCleanSession(true)
	connNewOpts.SetUsername(username)
	connNewOpts.SetPassword(password)
	tlsConfig := &tls.Config{InsecureSkipVerify: true, ClientAuth: tls.NoClientCert}
	connNewOpts.SetTLSConfig(tlsConfig)

	clientNew := MQTT.NewClient(connNewOpts)
	if token := clientNew.Connect(); token.Wait() && token.Error() != nil {
		errNew := utils.NewError(utils.ErrorTypeStop, token.Error().Error(), "MQTT设备控制,mqtt连接失败")
		utils.MyPrint(utils.PRINT_ERROR, "SendData2DeviceMQTT:5,", errNew)
	}
	connOpts.OnConnectionLost = func(client MQTT.Client, err error) {
		if client != nil {
			client.Disconnect(0)
		}
		clientNew = MQTT.NewClient(connNewOpts)
		if token := clientNew.Connect(); token.Wait() && token.Error() != nil {
			errNew := utils.NewError(utils.ErrorTypeStop, token.Error().Error(), "MQTT设备控制,mqtt连接失败")
			utils.MyPrint(utils.PRINT_ERROR, "SendData2DeviceMQTT:5,", errNew)
		}
		makeNewClientHandler(&clientNew)
	}
	makeNewClientHandler(&clientNew)
}

func MqttNoticeSend(key, data string) error {
	return MqttNoticeSendNoHeader("/"+appName+"/"+key, data)
}

func MqttNoticeSendNoHeader(key, data string) error {
	if clientConnected != nil {
		(*clientConnected).Publish(key, 0, false, data)
		utils.MyPrintCaller(utils.PRINT_WARN, 3, "mqtt send:", key, data)
	} else {
		errNew := utils.NewError(utils.ErrorTypeStop, "MqttNoticeSendNoHeader: clientConnected为nil")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return errNew
	}
	return nil
}
